#ifndef _NGX_EV_H_INCLUDED_
#define _NGX_EV_H_INCLUDED_

#include <ngx_config.h>
#include <ngx_core.h>


typedef struct {
	void    **main_conf;
	void    **srv_conf;
	void    **app_conf;
} ngx_ev_conf_ctx_t;

typedef struct {
	u_char                 	sockaddr[NGX_SOCKADDRLEN];
	socklen_t               	socklen;
	ngx_ev_conf_ctx_t			*ctx;
	unsigned                	bind:1;
	unsigned                	wildcard:1;
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
	unsigned                	ipv6only:2;
#endif
	unsigned                	so_keepalive:2;
	unsigned                	proxy_protocol:1;
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
	int                     	tcp_keepidle;
	int                     	tcp_keepintvl;
	int                     	tcp_keepcnt;
#endif

	ngx_uint_t				type;

} ngx_ev_listen_t;

typedef struct {
	ngx_ev_conf_ctx_t  *ctx;
	ngx_str_t               	addr_text;
	unsigned                	proxy_protocol:1;
} ngx_ev_addr_conf_t;

typedef struct {
	in_addr_t                	addr;
	ngx_ev_addr_conf_t     	conf;
} ngx_ev_in_addr_t;



#if (NGX_HAVE_INET6)

typedef struct {
	struct in6_addr         	addr6;
	ngx_ev_addr_conf_t     	conf;
} ngx_ev_in6_addr_t;

#endif


typedef struct {
	void                   	*addrs;
	ngx_uint_t              	naddrs;
} ngx_ev_port_t;


typedef struct {
	int                     	family;
	in_port_t               	port;
	ngx_array_t             	addrs;       /* array of ngx_rtmp_conf_addr_t */
} ngx_ev_conf_port_t;

typedef struct {
	struct sockaddr        	*sockaddr;
	socklen_t               	socklen;
	ngx_ev_conf_ctx_t			*ctx;
	unsigned                	bind : 1;
	unsigned                	wildcard : 1;
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
	unsigned                	ipv6only : 2;
#endif

} ngx_ev_conf_addr_t;




typedef struct ngx_ev_core_main_conf_s{
	ngx_array_t             	servers;
	ngx_array_t             	listen;
} ngx_ev_core_main_conf_t;

typedef struct ngx_ev_core_srv_conf_s {
	ngx_ev_conf_ctx_t    		*ctx;
} ngx_ev_core_srv_conf_t;

typedef struct ngx_ev_core_app_conf_s {
	ngx_array_t             	servers;
	ngx_array_t             	listen;
} ngx_ev_core_app_conf_s;


typedef struct {
	ngx_int_t   	(*preconfiguration)(ngx_conf_t *cf);
	ngx_int_t   	(*postconfiguration)(ngx_conf_t *cf);
	void*       	(*create_main_conf)(ngx_conf_t *cf);
	char*       	(*init_main_conf)(ngx_conf_t *cf, void *conf);
	void*       	(*create_srv_conf)(ngx_conf_t *cf);
	char*       	(*merge_srv_conf)(ngx_conf_t *cf, void *prev,void *conf);
	void*       	(*create_app_conf)(ngx_conf_t *cf);
	char*       	(*merge_app_conf)(ngx_conf_t *cf, void *prev,void *conf);
} ngx_ev_module_t;


#define NGX_EV_MAIN_CONF_OFFSET  offsetof(ngx_ev_conf_ctx_t, main_conf)
#define NGX_EV_SRV_CONF_OFFSET   offsetof(ngx_ev_conf_ctx_t, srv_conf)
#define NGX_EV_APP_CONF_OFFSET   offsetof(ngx_ev_conf_ctx_t, app_conf)



#define ngx_ev_conf_get_module_main_conf(cf, module)                       \
	((ngx_ev_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
#define ngx_ev_conf_get_module_srv_conf(cf, module)                        \
	((ngx_ev_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index]
#define ngx_ev_conf_get_module_app_conf(cf, module)                        \
	((ngx_ev_conf_ctx_t *) cf->ctx)->app_conf[module.ctx_index]


#define ngx_ev_get_module_ctx(s, module)     (s)->ctx[module.ctx_index]
#define ngx_ev_set_ctx(s, c, module)         s->ctx[module.ctx_index] = c;
#define ngx_ev_delete_ctx(s, module)         s->ctx[module.ctx_index] = NULL;


#define NGX_EV_MODULE		0xFFFFFFFF /* "EV" */
#define NGX_EV_MAIN_CONF	0x20000FF
#define NGX_EV_SRV_CONF		0x040000FF
#define NGX_EV_APP_CONF		0x080000FF
#define NGX_EV_REC_CONF		0x160000FF

extern ngx_uint_t ngx_ev_max_module;
extern ngx_module_t ngx_ev_core_module;

#endif /* _NGX_EV_H_INCLUDED_ */
